namespace SimpleWebServices.Configuration
{
    using System.Xml.XPath;
    using SimpleWebServices.Models;
    using SimpleWebServices.Web;
    using SimpleWebServices.Web.UI.Html.Elements;
    using Xunit;

    public sealed class InternalServerErrorSettingsFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<InternalServerErrorSettings>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .XmlRoot("error")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            string xml = 
                "<error enabled='true'>" +
                    "<notification>" +
                        "<from address='john.doe@example.com' name='John Doe' />" +
                        "<to><recipient address='jane.doe@example.com' name='Jane Doe' /></to>" +
                    "</notification>" +
                "</error>";

            InternalServerErrorSettings actual = xml.Deserialize<InternalServerErrorSettings>();

            Assert.True(actual.Enabled);

            Assert.Equal<string>("john.doe@example.com", actual.Notification.From.Address);
            Assert.Equal<string>("John Doe", actual.Notification.From.Name);

            Assert.Equal<int>(1, actual.Notification.To.Count);
            Assert.Equal<string>("jane.doe@example.com", actual.Notification.To[0].Address);
            Assert.Equal<string>("Jane Doe", actual.Notification.To[0].Name);
        }

        [Fact]
        public void deserializeWithoutNames()
        {
            string xml =
                "<error enabled='true'>" +
                    "<notification>" +
                        "<from address='john.doe@example.com' />" +
                        "<to><recipient address='jane.doe@example.com' /></to>" +
                    "</notification>" +
                "</error>";

            InternalServerErrorSettings actual = xml.Deserialize<InternalServerErrorSettings>();

            Assert.True(actual.Enabled);

            Assert.Equal<string>("john.doe@example.com", actual.Notification.From.Address);
            Assert.Null(actual.Notification.From.Name);

            Assert.Equal<int>(1, actual.Notification.To.Count);
            Assert.Equal<string>("jane.doe@example.com", actual.Notification.To[0].Address);
            Assert.Null(actual.Notification.To[0].Name);
        }

        [Fact]
        public void serialize()
        {
            InternalServerErrorSettings obj = new InternalServerErrorSettings
            {
                Enabled = true,
                Notification = new Notification
                {
                    From = new Email("john.doe@example.com", "John Doe"),
                    To =
                    {
                        new Email("jane.doe@example.com", "Jane Doe")
                    }
                }
            };

            XPathNavigator navigator = obj.Serialize().CreateNavigator();

            Assert.True((bool)navigator.Evaluate("1=count(/error[@enabled='true']/notification/from[@address='john.doe@example.com'][@name='John Doe'])"));
            Assert.True((bool)navigator.Evaluate("1=count(/error[@enabled='true']/notification/to/recipient[@address='jane.doe@example.com'][@name='Jane Doe'])"));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new InternalServerErrorSettings());
        }

        [Fact]
        public void prop_Enabled()
        {
            Assert.True(new PropertyExpectations(typeof(InternalServerErrorSettings).GetProperty("Enabled"))
                .XmlAttribute("enabled")
                .TypeIs<bool>()
                .Result);
        }

        [Fact]
        public void prop_Notification()
        {
            Assert.True(new PropertyExpectations(typeof(InternalServerErrorSettings).GetProperty("Notification"))
                .XmlElement("notification")
                .TypeIs<Notification>()
                .Result);
        }
    }
}